package com.mynetty.netty02.server;

import java.io.UnsupportedEncodingException;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class ServerHelloWorld {

	//监听线程组，监听客户端请求 
	private EventLoopGroup accepttorGroup=null;
	//处理客户端相关操作线程组，负责处理与客户端的数据通讯
	private EventLoopGroup clientGroup=null;
	// 服务启动相关配置信息
	private ServerBootstrap bootstrap = null;
	
	public ServerHelloWorld(){
		
		init();
	}
	
	private void init(){
		
		accepttorGroup = new NioEventLoopGroup();
		clientGroup = new NioEventLoopGroup();
		bootstrap = new ServerBootstrap();
		//绑定线程组
		bootstrap.group(accepttorGroup, clientGroup);
		//设定通讯模式为NIO
		bootstrap.channel(NioServerSocketChannel.class);
		//BACKLOG用于构造服务端套接字ServerSocket对象，标识当服务器请求处理线程全满时，
		//用于临时存放已完成三次握手的请求的队列的最大长度。
		//如果未设置或所设置的值小于1，Java将使用默认值50。
		bootstrap.option(ChannelOption.SO_BACKLOG, 1024);//连接排队数
		//SO_SNDBUF为发送缓冲区
		bootstrap.option(ChannelOption.SO_SNDBUF, 16*1024);
		//SO_RCVBUF为接受缓冲区
		bootstrap.option(ChannelOption.SO_RCVBUF, 16*1024);
		//SO_KEEPALIVE表示心跳检测，保证连接有效
		bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
	}
	
	public ChannelFuture doAccept(int port,final ChannelHandler... acceptorHandlers) throws InterruptedException{
	
		bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {

			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				ch.pipeline().addLast(acceptorHandlers);
			}
		});
		ChannelFuture future=bootstrap.bind(port).sync();
		
		return future;
	}
	
	public void release(){
		this.accepttorGroup.shutdownGracefully();
		this.clientGroup.shutdownGracefully();
	}
	
	
	public static void main(String[] args) throws UnsupportedEncodingException {
		ChannelFuture future=null;
		ServerHelloWorld server=null;
		try{
			server=new ServerHelloWorld();
			future=server.doAccept(9999, new ServerHelloWorldHandler());
			System.out.println("server started:");
			
			future.channel().closeFuture().sync();
		}
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}finally
		{
			if(null != future)
			{
				try{
					future.channel().closeFuture().sync();
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
			if(null != server)
			{
				server.release();
			}
		}
	}
	
}
